package com.sanri.tools.modules.mock.l7.websocket.client;

import com.sanri.tools.modules.core.exception.ToolException;
import com.sanri.tools.modules.mock.l7.websocket.event.*;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class WebsocketClientService implements ApplicationListener<WebsocketEvent> {


    /**
     * wsurl => CustomWebsocketClient
     */
    private Map<URI,CustomWebsocketClient> websocketClientMap = new ConcurrentHashMap<>();

    /**
     * 连接一个 websocket
     * @param uri
     * @throws URISyntaxException
     */
    public void connect(String uri) throws URISyntaxException {
        final URI uriObject = new URI(uri);
        final CustomWebsocketClient customWebsocketClient = new CustomWebsocketClient(uriObject);
        customWebsocketClient.connect();
        websocketClientMap.put(uriObject, customWebsocketClient);
    }

    /**
     * 发送一个文本消息到 websocket
     * @param uri
     * @param message
     * @throws URISyntaxException
     */
    public void sendMessageToServer(String uri, String message) throws URISyntaxException {
        final URI uriObject = new URI(uri);
        final CustomWebsocketClient websocketClient = websocketClientMap.get(uriObject);
        if (websocketClient == null){
            throw new ToolException("当前地址还未连接");
        }
        websocketClient.send(message);
    }

    /**
     * 关闭 websocket 连接
     * @param uri
     * @throws URISyntaxException
     */
    public void close(String uri) throws URISyntaxException {
        final URI uriObject = new URI(uri);
        final CustomWebsocketClient remove = websocketClientMap.remove(uriObject);
        if (remove != null){
            remove.close(0,"正常手动关闭");
        }
    }

    /**
     * 处理 websocket 消息
     * @param websocketEvent
     */
    public void handleMessage(MessageWebsocketEvent websocketEvent){
        log.info("收到消息: {}", websocketEvent.getMessage());

    }

    @Override
    public void onApplicationEvent(WebsocketEvent websocketEvent) {
        final Object source = websocketEvent.getSource();
        if (!(source instanceof CustomWebsocketClient)){
            return ;
        }
        final WebsocketEvent.MessageType messageType = websocketEvent.messageType();
        switch (messageType){
            case CONNECT:
                ConnectWebsocketEvent connectWebsocketEvent = (ConnectWebsocketEvent) websocketEvent;
                ServerHandshake serverHandshake = (ServerHandshake) connectWebsocketEvent.getHandshakedata();
                break;
            case MESSAGE:
                handleMessage((MessageWebsocketEvent)websocketEvent);
                break;
            case CLOSE:
                CloseWebsocketEvent closeWebsocketEvent = (CloseWebsocketEvent) websocketEvent;
                log.error("socket 已经被关闭: {}{}{}", closeWebsocketEvent.getCode(), closeWebsocketEvent.getReason(),closeWebsocketEvent.isRemote());
                break;
            case ERROR:
                ErrorWebsocketEvent errorWebsocketEvent = (ErrorWebsocketEvent) websocketEvent;
                log.error("异常: {}",errorWebsocketEvent.getException());
                break;
        }
    }

}
